#include "PrecompiledHeaders.h"
#include "ThirdPersonCamera.h"
#include "Ball.h"

/*
 * Sets up up to three camera based on the NULLness of the arguments. Sets the
 * position, direction and pitch of the cameras to simulate a third person
 * camera. Side camera are yawed to give a panoramic effect
 */
ThirdPersonCamera::ThirdPersonCamera(Ogre::Viewport *m_v, Ogre::Viewport *l_v,
    Ogre::Viewport *r_v, Ogre::SceneManager *sm) :
        ChaseCameraControl(m_v, l_v, r_v, sm, "tp_")
{
    original_pitch = -Constants::MAX_ANGLE;
    position = Ogre::Vector3(0, 7, 14);
    l_offset = Ogre::Vector3(-6, 0, 0);
    Ogre::Vector3 look_at(0, 7, 0);
    Ogre::Radian yaw_angle(1.4);
    Ogre::Real clip_distance(1);
    main_camera->setPosition(position);
    main_camera->lookAt(look_at);
    main_camera->setNearClipDistance(clip_distance);
    main_camera->pitch(original_pitch);
    if(l_v)
    {
        left_camera->setPosition(position + l_offset);
        left_camera->lookAt(look_at);
        left_camera->setNearClipDistance(clip_distance);
        left_camera->yaw(yaw_angle);
        left_camera->pitch(original_pitch);
    }
    if(r_v)
    {
        right_camera->setPosition(position - l_offset);
        right_camera->lookAt(look_at);
        right_camera->setNearClipDistance(clip_distance);
        right_camera->yaw(-yaw_angle);
        right_camera->pitch(original_pitch);
    }
    time_ago_since_ball_seen = 0;
    time_since_last_scaled = 0;
    d_IN = 0;
    d_OUT = 1;
    direction = d_IN;
}

void ThirdPersonCamera::updateScale(float time)
{
    previous_scale = position_scale;
    OgreNewt::BasicRaycast ray_one(ogre_newt, main_camera->getRealPosition(), player->getBall()->getPosition() + Ogre::Vector3(0, 0.5, 0));
    OgreNewt::BasicRaycast ray_two(ogre_newt, main_camera->getRealPosition(), player->getBall()->getPosition() - Ogre::Vector3(0, 0.5, 0));
    if(ray_one.getFirstHit().mBody != player->getBall()->getOgreNewtBody()
        && ray_two.getFirstHit().mBody != player->getBall()->getOgreNewtBody())
    {
        time_ago_since_ball_seen += time;
        if(time_ago_since_ball_seen > Constants::MAX_TIME_BALL_NOT_SEEN)
        {
            if(direction == d_IN || time_since_last_scaled > 0.5)
            {
                position_scale *= 0.99;
                direction = d_IN;
                time_since_last_scaled = 0;
            }
        }
    }
    else
    {
        time_ago_since_ball_seen = 0;
        if(position_scale < 1.0)
        {
            if(direction == d_OUT || time_since_last_scaled > 0.5)
            {
                position_scale /= 0.99;
                direction = d_OUT;
                time_since_last_scaled = 0;
            }
        }
        else position_scale = 1.0;
    }
    time_since_last_scaled += time;
}
